/* Copyright 2009 Sony Mathew, Minneapolis MN. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */
package com.xsm.lite.event;

import java.util.List;

/**
 * Manages Event.Listeners for the firing of Events.
 * 
 * Notes: 
 * Only holds Listeners, does NOT hold Events, only ability to fire them to interested listeners.
 * 
 * @author Sony Mathew
 */
public interface EventManager extends RequestEvent.Mediator {

    /**
     * Indicate interest in a particular event.  The Listener must explicitly 
     *  implement the passed in Event's Listener type.
     * 
     * You cannot listen to event base types, you will never hear them, since events are fired
     *  only to Listeners of that event's specific class type - Instead use addCategoryListener()
     *      for a more general class category based listening of events. 
     *   
     * author Sony Mathew
     */
    public void addListener(Class<? extends Event> eventClass, Event.Listener l);

    /**
     * If interested in a particular category of events (identified by event's class or any of its super classes). 
     * Register a CategoryEvent.Listener and you will be delivered a CategoryEvent for each event that fits the category.
     * 
     * Category Listeners are notified FIRST before actual Listeners of a specific fired Event. 
     * The Category Listeners can choose to consume the fired specific Event such that it is
     *    NOT propogated to its Listeners.
     *  
     * All Category Listeners registered for a matching category get a crack at the specific Event 
     *    regardless of whether it was consumed midstream, it is infact the specific fired Event that is consumed 
     *       and therefore NOT propogated to its Listeners.
     *       
     * Categories are class types in the event's class heirarchy.
     *    Only the Event's class and super classes form category heirarchy not interfaces.
     *    
     * Order of Category Listeners notified are from narrowest to broadest class in heirarchy.
     * 
     * author Sony Mathew
     */
    public void addCategoryListener(Class<? extends Event> eventCategory, CategoryEvent.Listener l);
    
    /**
     * Fire an event, so all listeners hear about it.
     * 
     * Registered Category Listeners are notified FIRST before actual Listeners of this specific Event. 
     * The Category Listeners can choose to consume this specific fired Event such that it is 
     *    NOT propogated to its Listeners.
     *    
     * @see #addCategoryListener(Class, com.xsm.lite.event.CategoryEvent.Listener)
     * @see #addListener(Class, com.xsm.lite.event.Event.Listener)
     * author Sony Mathew
     */
    public void fire(Event e);
    
    /**
     * Remove the given listener for just the given event type.
     * Can be a Category Listener or regular Listener.
     * 
     * author Sony Mathew
     */    
    public void removeListener(Class<? extends Event> eventClass, Event.Listener l);
    
    /**
     * Remove this listener completely for all events it listens to.
     * Can be a Category Listener or regular Listener.
     *  
     * author Sony Mathew
     */    
    public void removeListener(Event.Listener l);

    /**
     * Removes all Listeners listening to events of given event type
     *  This includes Category Listeners of this class category and regular listeners of this class type.
     *  Note: Does not remove this listener from listening to other event types.
     * 
     * author Sony Mathew
     */    
    public void removeListeners(Class<? extends Event> eventClass);
       
    /**
     * Removes everything.
     * 
     * author Sony Mathew
     */
    public void clear();
    
    /**
     * @return : List<Object>: A hard loop through all internally stored objects.
     *  for debugging purposes.  Cannot rebuild from this snapshot.
     * 
     * author Sony Mathew
     */
    public List<Object> snapshot();
}
